package org.jeecg.modules.demo.gmslopedata1.controller;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import java.lang.ref.SoftReference;
import java.net.URL;
import java.net.URLEncoder;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.Transaction;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureReader;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.filter.text.ecql.ECQL;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.geotools.data.Query;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.query.QueryRuleEnum;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.gmhazardparameters.entity.GmHazardParameters;
import org.jeecg.modules.demo.gmhazardparameters.service.IGmHazardParametersService;
import org.jeecg.modules.demo.gmslopedata1.entity.GmSlopeData1;
import org.jeecg.modules.demo.gmslopedata1.service.IGmSlopeData1Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.demo.gmtreatmentmeasures.entity.GmTreatmentMeasures;
import org.jeecg.modules.demo.gmtreatmentmeasures.service.IGmTreatmentMeasuresService;
import org.jeecg.modules.demo.rockslopestablesetting.entity.RockSlopeStableSetting;
import org.jeecg.modules.demo.rockslopestablesetting.service.IRockSlopeStableSettingService;
import org.jeecg.modules.demo.sloperiskevaluationsetting.entity.SlopeRiskEvaluationSetting;
import org.jeecg.modules.demo.sloperiskevaluationsetting.service.ISlopeRiskEvaluationSettingService;
import org.jeecg.modules.demo.slopestablesetting.entity.SlopeStableSetting;
import org.jeecg.modules.demo.slopestablesetting.service.ISlopeStableSettingService;
import org.jeecg.modules.demo.soilrockslopesetting.entity.SoilRockSlopeSetting;
import org.jeecg.modules.demo.soilrockslopesetting.service.ISoilRockSlopeSettingService;
import org.jeecg.common.system.base.controller.JeecgController;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.index.strtree.STRtree;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;

 /**
 * @Description: 边坡数据
 * @Author: jeecg-boot
 * @Date:   2025-06-24
 * @Version: V1.0
 */
@Api(tags="边坡数据")
@RestController
@RequestMapping("/gmslopedata1/gmSlopeData1")
@Slf4j
public class GmSlopeData1Controller extends JeecgController<GmSlopeData1, IGmSlopeData1Service> {
	@Autowired
	private IGmSlopeData1Service gmSlopeData1Service;
	 private static final String CACHE_KEY_SLOPE = "config:slope_stable_setting";
	 private static final String CACHE_KEY_ROCK_SLOPE = "config:rock_slope_stable_setting";
	 private static final String CACHE_KEY_SOIL_ROCK_SLOPE = "config:soil_rock_slope_stable_setting";
	 private static final String CACHE_KEY_SLOPE_RISK = "config:slope_risk_evaluation_setting";
	 private static final String CACHE_KEY_HAZARD_PARAMETERS= "config:gm_hazard_parameters";
	 @Autowired
	 private RedisUtil redisUtil;
	 @Autowired
	 private ISlopeStableSettingService slopeStableSettingService;

	 @Autowired
	 private IRockSlopeStableSettingService rockSlopeStableSettingService;

	 @Autowired
	 private ISoilRockSlopeSettingService soilRockSlopeSettingService;

	 @Autowired
	 private ISlopeRiskEvaluationSettingService slopeRiskEvaluationSettingService;
//	 // 注入自定义线程池
//	 @Autowired
//	 @Qualifier("gmDataThreadPool")
//	 private ThreadPoolTaskExecutor taskExecutor;
	 @Autowired
	 private IGmTreatmentMeasuresService gmTreatmentMeasuresService;
	 @Autowired
	 private IGmHazardParametersService gmHazardParametersService;


	
	/**
	 * 分页列表查询
	 *
	 * @param gmSlopeData1
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	//@AutoLog(value = "边坡数据-分页列表查询")
	@ApiOperation(value="边坡数据-分页列表查询", notes="边坡数据-分页列表查询")
	@GetMapping(value = "/list")
	public Result<IPage<GmSlopeData1>> queryPageList(GmSlopeData1 gmSlopeData1,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
        // 自定义查询规则
        Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
        // 自定义多选的查询规则为：LIKE_WITH_OR
        customeRuleMap.put("slopeType", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("soilLooseness", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("overlyingSoilType", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("rockCharacteristics", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("fractureDevelopmentDegree", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("cutSlopeHeight", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("cutSlopeGradient", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("cutSlopeShape", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("naturalSlopeGradient", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("vegetationCoverage", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("governanceMeasures", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("slopeWallDistance", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("cutSlopeWidth", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("cutSlopeTime", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("resident", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("threatPopulation", QueryRuleEnum.LIKE_WITH_OR);
        customeRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
        QueryWrapper<GmSlopeData1> queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData1, req.getParameterMap(),customeRuleMap);
		Page<GmSlopeData1> page = new Page<GmSlopeData1>(pageNo, pageSize);
		IPage<GmSlopeData1> pageList = gmSlopeData1Service.page(page, queryWrapper);
		return Result.OK(pageList);
	}
	
	/**
	 *   添加
	 *
	 * @param gmSlopeData1
	 * @return
	 */
	@AutoLog(value = "边坡数据-添加")
	@ApiOperation(value="边坡数据-添加", notes="边坡数据-添加")
	@RequiresPermissions("gmslopedata1:gm_slope_data1:add")
	@PostMapping(value = "/add")
	public Result<String> add(@RequestBody GmSlopeData1 gmSlopeData1) {
		gmSlopeData1Service.save(gmSlopeData1);
		return Result.OK("添加成功！");
	}

	 /**
	  *   添加
	  *
	  * @param gmSlopeData1
	  * @return
	  */
	 @AutoLog(value = "边坡数据-添加")
	 @ApiOperation(value="边坡数据-添加", notes="边坡数据-添加")
	 @PostMapping(value = "/result")
	 public Result<String> result(@RequestBody GmSlopeData1 gmSlopeData1) {

		 Map<String, Double> yValues = calculateYValues(gmSlopeData1);
		 Double y = yValues.get("Y");
		 Double y4 = yValues.get("Y4");

//			 切坡稳定性等级	稳定	较稳定	较不稳定	不稳定
//			 稳定性指数Yi	1.75≤Yi	1.75＜Yi≤2.5	2.5＜Yi≤3.25	Yi＞3.25

		 if (y <= 1.75) {
			 gmSlopeData1.setResult("稳定");
			 System.out.println("稳定");
		 }else if (y > 1.75 && y <= 2.5) {
			 gmSlopeData1.setResult("较稳定");
			 System.out.println("较稳定");
		 }else if (y > 2.5 && y <= 3.25) {
			 gmSlopeData1.setResult("较不稳定");
			 System.out.println("较不稳定");
		 }else {
			 gmSlopeData1.setResult("不稳定");
			 System.out.println("不稳定");
		 }
//			 gmSlopeData1Service.updateById(gmSlopeData1);
		 if (y4!= null){
			 System.out.println("yValues.get(\"Y4\") = " + yValues.get("Y4"));
//			 切坡危险性等级	极高危险	高危险	中危险	低危险
//			 危险性指数Hi	0.85≤Hi	0.75≤Hi＜0.85	0.65≤Hi＜0.75	Hi＜0.65
			 if(y4<=0.65){
				 System.out.println("低危险");
			 }else if (y4 > 0.65 && y4 <= 0.75) {
				 System.out.println("中危险");
			 }else if (y4 > 0.75 && y4 < 0.85) {
				 System.out.println("高危险");
			 }else if (y4 >= 0.85){
				 System.out.println("极高危险");
			 }
			 LambdaQueryWrapper<GmTreatmentMeasures> queryWrapper = new LambdaQueryWrapper<>();
			 queryWrapper.eq(GmTreatmentMeasures::getCutSlopeHeight, gmSlopeData1.getCutSlopeHeight())
					 .eq(GmTreatmentMeasures::getSlopeType, gmSlopeData1.getSlopeType())
					 .eq(GmTreatmentMeasures::getSlopeWallDistance, gmSlopeData1.getSlopeWallDistance())
					 .eq(GmTreatmentMeasures::getNaturalSlopeGradient, gmSlopeData1.getNaturalSlopeGradient());
			 if (gmSlopeData1.getSlopeType().equals("A")){
				 //岩质
				 queryWrapper.eq(GmTreatmentMeasures::getType1, gmSlopeData1.getRockCharacteristics());

			 } else if (gmSlopeData1.getSlopeType().equals("C")) {
				 //土质
				 queryWrapper.eq(GmTreatmentMeasures::getType1, gmSlopeData1.getSoilLooseness());
			 }
			 List<GmTreatmentMeasures> list = gmTreatmentMeasuresService.list(queryWrapper);
			 if(oConvertUtils.isNotEmpty(list)){
				 list.stream()
						 .map(gmTreatmentMeasures -> {
							 gmSlopeData1.setMeasure(gmTreatmentMeasures.getId()+",");
                             return null;
                         });
			 }
		 }

		 return Result.OK("添加成功！");
	 }
	 /**
	  *   添加
	  *
	  * @return
	  */
	 @AutoLog(value = "边坡数据-添加")
	 @ApiOperation(value="边坡数据-添加", notes="边坡数据-添加")
	 @PostMapping(value = "/resultOne")
	 public Result<String> resultOne() {
		 GmSlopeData1 gmSlopeData1 = gmSlopeData1Service.getById("1937406058333917194");

			 Map<String, Double> yValues = calculateYValues(gmSlopeData1);
			 // 将计算结果保存到 GmSlopeData1 对象中
			 System.out.println("yValues.get(\"Y\") = " + yValues.get("Y"));
			 //Y4可能不存在
			 if (yValues.get("Y4") != null){
				 System.out.println("yValues.get(\"Y4\") = " + yValues.get("Y4"));
			 }
//			 切坡稳定性等级	稳定	较稳定	较不稳定	不稳定
//			 稳定性指数Yi	1.75≤Yi	1.75＜Yi≤2.5	2.5＜Yi≤3.25	Yi＞3.25
			 Double y = yValues.get("Y");
			 if (y <= 1.75) {
				 gmSlopeData1.setResult("稳定");
				 System.out.println("稳定");
			 }else if (y > 1.75 && y <= 2.5) {
				 gmSlopeData1.setResult("较稳定");
				 System.out.println("较稳定");
			 }else if (y > 2.5 && y <= 3.25) {
				 gmSlopeData1.setResult("较不稳定");
				 System.out.println("较不稳定");
			 }else {
				 gmSlopeData1.setResult("不稳定");
				 System.out.println("不稳定");
			 }
			 gmSlopeData1Service.updateById(gmSlopeData1);
		 // 计算 Y1, Y2, Y3
		 return Result.OK("添加成功！");
	 }

	 private final AtomicInteger threadNum5 = new AtomicInteger(0);
	 private final AtomicInteger threadNum6 = new AtomicInteger(0);


	 /**
	  *   添加
	  *
	  * @return
	  */
	 @AutoLog(value = "边坡数据-添加")
	 @ApiOperation(value = "边坡数据-添加", notes = "边坡数据-添加")
	 @PostMapping(value = "/resultAll")
	 public Result<String> resultAll() {
		 long start = System.currentTimeMillis();

		 List<GmSlopeData1> list = gmSlopeData1Service.list();
		 CompletableFuture<?>[] futures = list.stream()
				 .map(this::processGmSlopeData1)
				 .toArray(CompletableFuture[]::new);

		 CompletableFuture.allOf(futures).join();
		 long end = System.currentTimeMillis();
		 System.out.println(threadNum5.get());
		 System.out.println(threadNum6.get());
		 System.out.println("rate = " + threadNum5.get() / (double) threadNum6.get()*100+"%");
		 System.out.println("耗时：" + (end - start));

		 return Result.OK("添加成功！");
	 }

	 @Async("gmDataThreadPool")
	 public CompletableFuture<Void> processGmSlopeData1(GmSlopeData1 gmSlopeData1) {
		 Map<String, Double> yValues = calculateYValues(gmSlopeData1);
		 // 将计算结果保存到 GmSlopeData1 对象中
//		 System.out.println("yValues.get(\"Y\") = " + yValues.get("Y"));
		 //Y4可能不存在
		 if (yValues.get("Y4") != null) {
//			 System.out.println("yValues.get(\"Y4\") = " + yValues.get("Y4"));
		 }

		 Double y = yValues.get("Y");
		 if (y <= 1.75) {
			 gmSlopeData1.setResult("稳定");
			 System.out.println(gmSlopeData1.getArtificialStability() +"----稳定----"+y);
		 } else if (y > 1.75 && y <= 2.5) {
			 gmSlopeData1.setResult("较稳定");
			 System.out.println(gmSlopeData1.getArtificialStability() +"----较稳定----"+y);
		 } else if (y > 2.5 && y <= 3.25) {
			 gmSlopeData1.setResult("较不稳定");
			 System.out.println(gmSlopeData1.getArtificialStability() +"----较不稳定-----"+y);
		 } else {
			 gmSlopeData1.setResult("不稳定");
			 System.out.println(gmSlopeData1.getArtificialStability() +"----不稳定-----"+y);
		 }
		 if(gmSlopeData1.getResult().equals(gmSlopeData1.getArtificialStability())){
			 threadNum5.getAndIncrement();
		 }
		 threadNum6.getAndIncrement();

		 // 更新数据库记录
		 gmSlopeData1Service.updateById(gmSlopeData1);
		 return CompletableFuture.completedFuture(null);
	 }


	 /**
	  * 计算 Y1, Y2, Y3
	  *
	  * @param gmSlopeData
	  * @return
	  */
	 private Map<String, Double> calculateYValues(GmSlopeData1 gmSlopeData) {
		 Map<String, Double> yValues = new HashMap<>();

		 // 获取缓存中的配置
		 SlopeStableSetting slopeSetting = loadOrCacheConfig(CACHE_KEY_SLOPE, slopeStableSettingService);
		 RockSlopeStableSetting rockSlopeSetting = loadOrCacheConfig(CACHE_KEY_ROCK_SLOPE, rockSlopeStableSettingService);
		 SoilRockSlopeSetting soilRockSlopeSetting = loadOrCacheConfig(CACHE_KEY_SOIL_ROCK_SLOPE, soilRockSlopeSettingService);
		 SlopeRiskEvaluationSetting riskSetting = loadOrCacheConfig(CACHE_KEY_SLOPE_RISK, slopeRiskEvaluationSettingService);
		 GmHazardParameters hazardParameters = loadOrCacheConfig(CACHE_KEY_HAZARD_PARAMETERS, gmHazardParametersService);

		 if (slopeSetting == null || rockSlopeSetting == null || soilRockSlopeSetting == null || riskSetting == null) {
			 throw new RuntimeException("部分配置未找到，请检查Redis缓存或数据库是否正确加载");
		 }

		 // 根据 rockCharacteristics 决定使用哪个设置
		 //保留2位小数
		 double y=0.0;
		 String slopeType = gmSlopeData.getSlopeType();

		 if ("C".equals(slopeType)) {
			 // 计算土质边坡的 Y 值
//			 System.out.println("土质边评价");
			 y = Utils.calculateSlopeY(slopeSetting, gmSlopeData);
//			 System.out.println("y = " + y);
		 } else if ("A".equals(slopeType)) {
			 // 计算岩质边坡的 Y 值
//			 System.out.println("岩质边评价");
			 y = Utils.calculateRockY(rockSlopeSetting, gmSlopeData);
//			 System.out.println("y = " + y);
		 } else if ("B".equals(slopeType)) {
			 // 计算土岩质边坡的 Y 值
//			 System.out.println("土岩质边评价");
			 y = Utils.calculateSoilRockY(soilRockSlopeSetting, gmSlopeData);
//			 System.out.println("y3 = " + y);
		 }
		 yValues.put("Y", y);
		 if ((y>2.5)){
			 // 计算风险评估 Y4
			 //边坡危险性指数
			 double y4 = Utils.calculateDangerY(riskSetting, gmSlopeData);
			 Utils.calculateAndSetHazardLevels(y,y4,gmSlopeData,hazardParameters);
			  //边坡风险程度

//			 System.out.println("y4 = " + y4);
			 yValues.put("Y4", y4); // 如果需要也可以返回
		 }

		 return yValues;
	 }
	 /**
	  * 尝试从 Redis 获取缓存，若不存在则查询数据库并写入缓存
	  *
	  * @param cacheKey 缓存键名
	  * @param service 数据库服务
	  * @return 配置对象
	  */
	 private <T> T loadOrCacheConfig(String cacheKey, IService<T> service) {
		 T cached = (T) redisUtil.get(cacheKey);
		 if (cached != null) {
			 return cached;
		 }
		 T fromDb = service.getOne(new QueryWrapper<>());
		 if (fromDb != null) {
			 redisUtil.set(cacheKey, fromDb);
			 return fromDb;
		 }
		 log.warn("数据库中未找到对应配置，缓存 key: {}", cacheKey);
		 return null;
	 }



	 /**
	 *  编辑
	 *
	 * @param gmSlopeData1
	 * @return
	 */
	@AutoLog(value = "边坡数据-编辑")
	@ApiOperation(value="边坡数据-编辑", notes="边坡数据-编辑")
	@RequiresPermissions("gmslopedata1:gm_slope_data1:edit")
	@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
	public Result<String> edit(@RequestBody GmSlopeData1 gmSlopeData1) {
		gmSlopeData1Service.updateById(gmSlopeData1);
		return Result.OK("编辑成功!");
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "边坡数据-通过id删除")
	@ApiOperation(value="边坡数据-通过id删除", notes="边坡数据-通过id删除")
	@RequiresPermissions("gmslopedata1:gm_slope_data1:delete")
	@DeleteMapping(value = "/delete")
	public Result<String> delete(@RequestParam(name="id",required=true) String id) {
		gmSlopeData1Service.removeById(id);
		return Result.OK("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "边坡数据-批量删除")
	@ApiOperation(value="边坡数据-批量删除", notes="边坡数据-批量删除")
	@RequiresPermissions("gmslopedata1:gm_slope_data1:deleteBatch")
	@DeleteMapping(value = "/deleteBatch")
	public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.gmSlopeData1Service.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	//@AutoLog(value = "边坡数据-通过id查询")
	@ApiOperation(value="边坡数据-通过id查询", notes="边坡数据-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<GmSlopeData1> queryById(@RequestParam(name="id",required=true) String id) {
		GmSlopeData1 gmSlopeData1 = gmSlopeData1Service.getById(id);
		if(gmSlopeData1==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(gmSlopeData1);
	}

    /**
    * 导出excel
    *
    * @param request
    * @param gmSlopeData1
    */
//    @RequiresPermissions("gmslopedata1:gm_slope_data1:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, GmSlopeData1 gmSlopeData1) {
        return super.exportXls(request, gmSlopeData1, GmSlopeData1.class, "边坡数据");
    }


	 /**
	  * 导出excel多张图片
	  *
	  * @param request
	  */
	 @RequiresPermissions("gmslopedata1:gm_slope_data1:exportXls")
	 @ApiOperation(value="边坡数据-导出excel多张图片", notes="边坡数据-导出excel多张图片")
//	 @RequestMapping(value = "/exportXls1")
	 @PostMapping(value = "/exportXls1")
	 public Result<byte[]> exportXls1(HttpServletRequest request, HttpServletResponse response, GmSlopeData1 gmSlopeData1) throws IOException {
		 // Step.1 组装查询条件
		 QueryWrapper<GmSlopeData1> queryWrapper =new QueryWrapper<>(gmSlopeData1);
		 // 过滤选中数据
		 String selections = request.getParameter("selections");
		 System.out.println("selections = " + selections);
		 if (oConvertUtils.isNotEmpty(selections)) {
			 List<String> selectionList = Arrays.asList(selections.split(","));
			 System.out.println("selectionList = " + selectionList);
			 queryWrapper.in("id",selectionList);
		 }
		 // Step.2 获取导出数据
		 List<GmSlopeData1> exportList = gmSlopeData1Service.list(queryWrapper);
//		 System.out.println("exportList = " + exportList);
//		 return gmSlopeData1Service.exportXls(exportList);

//		 String outputPath = "D:\\\\桌面\\\\周报\\\\2025-汇报\\履职廉洁档案导出12.xlsx";

		 // 2. 生成Excel字节数组
		 byte[] excelBytes = gmSlopeData1Service.generateExcelBytes(exportList);

//		 // 3. 设置响应头（关键：触发浏览器下载）
//		 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Excel文件类型
//		 String fileName = "边坡治理方案.xlsx";
//		 // 处理中文文件名乱码（UTF-8编码）
//		 String encodedFileName = URLEncoder.encode(fileName, "UTF-8");
//		 response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
//		 response.setContentLength(excelBytes.length); // 设置文件大小（可选，但推荐）

		 // 4. 将字节数组写入响应流
//		 try (OutputStream os = response.getOutputStream()) {
//			 os.write(excelBytes);
//			 os.flush(); // 刷新流，确保数据全部发送
//		 }
		return Result.OK(excelBytes);
     }

	 /**
	  * 导出excel多张图片
	  *
	  * @param request
	  */
	 @RequiresPermissions("gmslopedata1:gm_slope_data1:exportXls")
	 @ApiOperation(value="边坡数据-导出excel多张图片", notes="边坡数据-导出excel多张图片")
	 @RequestMapping(value = "/exportXls2")
	 public Result<String> exportXls2(HttpServletRequest request, HttpServletResponse response, GmSlopeData1 gmSlopeData1) throws IOException {
		 // Step.1 组装查询条件
		 QueryWrapper<GmSlopeData1> queryWrapper =new QueryWrapper<>(gmSlopeData1);
		 // 过滤选中数据
		 String selections = request.getParameter("selections");
		 System.out.println("selections = " + selections);
		 if (oConvertUtils.isNotEmpty(selections)) {
			 List<String> selectionList = Arrays.asList(selections.split(","));
			 System.out.println("selectionList = " + selectionList);
			 queryWrapper.in("id",selectionList);
		 }else{
			 // 自定义查询规则
			 Map<String, QueryRuleEnum> customeRuleMap = new HashMap<>();
			 // 自定义多选的查询规则为：LIKE_WITH_OR
			 customeRuleMap.put("slopeType", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("soilLooseness", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("overlyingSoilType", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("rockCharacteristics", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("fractureDevelopmentDegree", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("cutSlopeHeight", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("cutSlopeGradient", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("cutSlopeShape", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("naturalSlopeGradient", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("vegetationCoverage", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("governanceMeasures", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("slopeWallDistance", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("cutSlopeWidth", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("cutSlopeTime", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("resident", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("threatPopulation", QueryRuleEnum.LIKE_WITH_OR);
			 customeRuleMap.put("threatHouse", QueryRuleEnum.LIKE_WITH_OR);
			  queryWrapper = QueryGenerator.initQueryWrapper(gmSlopeData1, request.getParameterMap(),customeRuleMap);
		 }
		 // Step.2 获取导出数据
		 List<GmSlopeData1> exportList = gmSlopeData1Service.list(queryWrapper);

		 if(exportList.size()==0||oConvertUtils.isEmpty(exportList)){
			 return Result.OK("没有数据");
		 }else if (exportList.size()>200){
			 return Result.error("数据量过大，请选择部分导出");
         }

//		 System.out.println("exportList = " + exportList);
//		 return gmSlopeData1Service.exportXls(exportList);

//		 String outputPath = "D:\\\\桌面\\\\周报\\\\2025-汇报\\履职廉洁档案导出12.xlsx";

		 // 2. 生成Excel字节数组
		 byte[] excelBytes = gmSlopeData1Service.generateExcelBytes(exportList);

		 // 3. 设置响应头（关键：触发浏览器下载）
		 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Excel文件类型
		 String fileName = "边坡治理方案.xlsx";
		 // 处理中文文件名乱码（UTF-8编码）
		 String encodedFileName = URLEncoder.encode(fileName, "UTF-8");
		 response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
		 response.setContentLength(excelBytes.length); // 设置文件大小（可选，但推荐）

		 // 4. 将字节数组写入响应流
		 try (OutputStream os = response.getOutputStream()) {
			 os.write(excelBytes);
			 os.flush(); // 刷新流，确保数据全部发送
		 }
		 return Result.OK("导出成功！");
	 }





    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequiresPermissions("gmslopedata1:gm_slope_data1:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, GmSlopeData1.class);
    }


//	 @AutoLog(value = "边坡数据-根据position查询边坡个数-导入专用")
//	 @ApiOperation(value="边坡数据-根据position查询边坡个数-导入专用", notes="边坡数据-根据position查询边坡个数-导入专用")
//	 @GetMapping(value = "/getSlopeCount")
//	 public Result<String> getSlopeCount(@RequestParam(name="town", required = true) String town,
//										 @RequestParam(name="village", required = true)String village) {
//		 LambdaQueryWrapper<GmSlopeData1> queryWrapper = new LambdaQueryWrapper<>();
//		 queryWrapper.eq(GmSlopeData1::getTown, town)
//				 .eq(GmSlopeData1::getVillage, village);
//		 int count = (int) gmSlopeData1Service.count(queryWrapper);
//		 String code = gmAdministrativeCodeService.getCodeByPosition(town, village);
//		 // 格式化为4位，不足补零
//		 String formattedCount = String.format("%04d", count+1);
//		 String number = code +'A'+formattedCount;
//		 return Result.OK(number);
//	 }

	 /**
	  * 异步通过excel导入数据
	  *
	  * @param request
	  * @param response
	  * @return
	  */
	 @RequiresPermissions("gmslopedata1:gm_slope_data1:importExcel")
	 @RequestMapping(value = "/importExcelCustom", method = RequestMethod.POST)
	 public Result<?> importExcelCustom(HttpServletRequest request, HttpServletResponse response) {
		 asyncImportExcel(request, response);
		 return Result.OK("数据后台导入中，请耐心等待");
	 }

	 @RequestMapping(value = "/importExcelTest", method = RequestMethod.POST)
	 public Result<?> importExcelTest(MultipartFile file) {
//		 List<GmSlopeData1> dataList = gmSlopeData1Service.readExcel(file);
		 asyncImportExcel1(file);
		 return Result.OK("数据后台导入中，请耐心等待");
	 }

	 @Async("gmDataThreadPool")
	 public void asyncImportExcel1(MultipartFile file) {
		 try {
			 gmSlopeData1Service.readExcel(file);
		 } catch (Exception e) {
			 log.error("Error during importing Excel data asynchronously", e);
		 }
	 }

	 @Async("gmDataThreadPool")
	 public void asyncImportExcel(HttpServletRequest request, HttpServletResponse response) {
		 try {
			 gmSlopeData1Service.importExcelCustom(request, response, GmSlopeData1.class);
		 } catch (Exception e) {
			 log.error("Error during importing Excel data asynchronously", e);
		 }
	 }

	 @Value("${gm.SockType}")
	 private String sockTypePath;

	 @Value("${gm.GeoType}")
	 private String geoTypePath;

	 // 优化1：静态初始化坐标系（避免重复解码）
	 private static final CoordinateReferenceSystem SOURCE_CRS;
	 private static final CoordinateReferenceSystem TARGET_CRS;
	 private static final MathTransform TRANSFORM;

	 static {
		 try {
			 System.setProperty("org.geotools.referencing.forceXY", "true");
			 SOURCE_CRS = CRS.decode("EPSG:4326");
			 TARGET_CRS = CRS.decode("EPSG:3857"); // 使用常用投影坐标系
			 TRANSFORM = CRS.findMathTransform(SOURCE_CRS, TARGET_CRS, true);
		 } catch (Exception e) {
			 throw new RuntimeException("CRS初始化失败", e);
		 }
	 }

	 // 优化2：增强DataStore缓存（使用软引用防止OOM）
	 private static final LoadingCache<String, DataStore> dataStoreCache = CacheBuilder.newBuilder()
			 .maximumSize(10) // 缓存最大数量
			 .softValues() // 使用软引用
			 .build(new CacheLoader<String, DataStore>() {
				 @Override
				 public DataStore load(String filePath) throws Exception {
					 URL url = new File(filePath).toURI().toURL();
					 Map<String, Object> params = new HashMap<>();
					 params.put("url", url);
					 params.put("charset", "GBK");
					 // 禁用内存映射
					 // params.put("memory mapped buffer", true);  // 启用内存映射
					 // params.put("cache and reuse memory maps", true);  // 重用内存映射

					 return DataStoreFinder.getDataStore(params);
				 }
			 });

	 @ApiOperation(value = "selectSockType3", notes = "selectSockType3")
	 @PostMapping("/selectSockType3")
	 public Result<Map<String, Object>> selectSockType3(@RequestBody JSONObject jsonObject) throws Exception {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");
		 log.info("longitude = " + longitude);

		 Map<String, Object> result = queryShapefile(
				 sockTypePath,
				 longitude,
				 latitude,
				 new String[]{"岩类", "岩类名称"},
				 "rockType"
		 );

		 return Result.ok(result);
	 }

	 @ApiOperation(value = "selectGeoType3", notes = "selectGeoType3")
	 @PostMapping("/selectGeoType3")
	 public Result<Map<String, Object>> selectGeoType3(@RequestBody JSONObject jsonObject) throws Exception {
		 double longitude = jsonObject.getDouble("longitude");
		 double latitude = jsonObject.getDouble("latitude");

		 Map<String, Object> result = queryShapefile(
				 geoTypePath,
				 longitude,
				 latitude,
				 new String[]{"gridcode"},  // 根据实际字段名调整
				 "slope"
		 );

		 return Result.ok(result);
	 }

	 private Map<String, Object> queryShapefile(String filePath, double longitude, double latitude,
												String[] attributeNames, String resultKey) {
		 Map<String, Object> result = new HashMap<>(attributeNames.length * 2); // 初始化HashMap大小
		 List<Map<String, String>> featuresList = new ArrayList<>();

		 DataStore dataStore = null;
		 SimpleFeatureIterator iterator = null;

		 try {
			 dataStore = dataStoreCache.get(filePath);
			 if (dataStore == null) {
				 result.put(resultKey + "_error", "无法加载数据源: " + filePath);
				 return result;
			 }

			 String typeName = dataStore.getTypeNames()[0];
			 SimpleFeatureType schema = dataStore.getSchema(typeName);

			 CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
			 CoordinateReferenceSystem targetCRS = schema.getCoordinateReferenceSystem();
			 MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);

			 GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
			 Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
			 Point transformedPoint = (Point) JTS.transform(point, transform);

			 Filter filter = ECQL.toFilter(
					 "INTERSECTS(the_geom, POINT(" + transformedPoint.getX() + " " + transformedPoint.getY() + "))"
			 );

			 SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);
			 SimpleFeatureCollection features = featureSource.getFeatures(filter);
			 iterator = features.features();

			 while (iterator.hasNext()) {
				 SimpleFeature feature = iterator.next();
				 Map<String, String> attributeMap = new HashMap<>(attributeNames.length); // 初始化HashMap大小
				 for (String attrName : attributeNames) {
					 Object value = feature.getAttribute(attrName);
					 attributeMap.put(attrName, value != null ? value.toString() : "N/A");
				 }
				 featuresList.add(attributeMap);
			 }

			 if ("rockType".equals(resultKey)) {
				 StringBuilder combinedValues = new StringBuilder();
				 for (Map<String, String> attrs : featuresList) {
					 String rockType = attrs.getOrDefault("岩类", "");
					 String rockTypeName = attrs.getOrDefault("岩类名称", "");
					 combinedValues.append(rockType).append(" ").append(rockTypeName.trim());
				 }
				 result.put(resultKey, combinedValues.toString());
			 } else if ("slope".equals(resultKey) && !featuresList.isEmpty()) {
				 String slopeValue = featuresList.get(0).get("gridcode");
				 try {
					 switch (slopeValue) {
						 case "1":
							 result.put(resultKey, "A 小于20°".trim());
							 break;
						 case "2":
							 result.put(resultKey, "B 20°-30°".trim());
							 break;
						 default:
							 result.put(resultKey, "C 大于30°".trim());
							 break;
					 }
				 } catch (NumberFormatException e) {
					 result.put(resultKey, slopeValue);
				 }
			 } else {
				 result.put(resultKey, featuresList);
			 }
		 } catch (Exception e) {
			 log.error("查询出错: {}", e.getMessage(), e);
			 result.put("error", e.getMessage());
		 } finally {
			 if (iterator != null) {
				 iterator.close();
			 }
		 }

		 return result;
	 }

}


//    /**
//     * 参数优化方法：自动调整前三个公式的参数以提升准确率
//     *
//     * @return 优化结果
//     */
//    @ApiOperation(value = "边坡参数自动优化", notes = "自动调整前三个公式参数以提升准确率")
//    @PostMapping("/optimizeParams")
//    public Result<String> optimizeParams() {
//        List<GmSlopeData1> dataList = gmSlopeData1Service.list();
//        double bestAccuracy = 0.0;
//        SlopeStableSetting bestSlopeSetting = null;
//        RockSlopeStableSetting bestRockSetting = null;
//        SoilRockSlopeSetting bestSoilRockSetting = null;
//        // 这里只做简单网格搜索示例，实际可用更高效算法
//        SlopeStableSetting slopeSetting = loadOrCacheConfig(CACHE_KEY_SLOPE, slopeStableSettingService);
//        RockSlopeStableSetting rockSetting = loadOrCacheConfig(CACHE_KEY_ROCK_SLOPE, rockSlopeStableSettingService);
//        SoilRockSlopeSetting soilRockSetting = loadOrCacheConfig(CACHE_KEY_SOIL_ROCK_SLOPE, soilRockSlopeSettingService);
//        if (slopeSetting == null || rockSetting == null || soilRockSetting == null) {
//            return Result.error("参数配置缺失");
//        }
//        // 假设只优化切坡高度权重，实际可扩展到更多参数
//        for (double hWeight = 0.05; hWeight <= 0.5; hWeight += 0.05) {
//            slopeSetting.setCutSlopeHeightWeight(hWeight);
//            rockSetting.setCutSlopeHeightWeight(hWeight);
//            soilRockSetting.setCutSlopeHeightWeight(hWeight);
//            int correct = 0;
//            int total = 0;
//            for (GmSlopeData1 data : dataList) {
//                String slopeType = data.getSlopeType();
//                double y = 0.0;
//                if ("C".equals(slopeType)) {
//                    y = Utils.calculateSlopeY(slopeSetting, data);
//                } else if ("A".equals(slopeType)) {
//                    y = Utils.calculateRockY(rockSetting, data);
//                } else if ("B".equals(slopeType)) {
//                    y = Utils.calculateSoilRockY(soilRockSetting, data);
//                } else {
//                    continue;
//                }
//                String result = "";
//                if (y <= 1.75) {
//                    result = "稳定";
//                } else if (y > 1.75 && y <= 2.5) {
//                    result = "较稳定";
//                } else if (y > 2.5 && y <= 3.25) {
//                    result = "较不稳定";
//                } else {
//                    result = "不稳定";
//                }
//                if (result.equals(data.getArtificialStability())) {
//                    correct++;
//                }
//                total++;
//            }
//            double accuracy = total > 0 ? correct * 1.0 / total : 0.0;
//            if (accuracy > bestAccuracy) {
//                bestAccuracy = accuracy;
//                bestSlopeSetting = new SlopeStableSetting();
//                bestRockSetting = new RockSlopeStableSetting();
//                bestSoilRockSetting = new SoilRockSlopeSetting();
//                org.springframework.beans.BeanUtils.copyProperties(slopeSetting, bestSlopeSetting);
//                org.springframework.beans.BeanUtils.copyProperties(rockSetting, bestRockSetting);
//                org.springframework.beans.BeanUtils.copyProperties(soilRockSetting, bestSoilRockSetting);
//            }
//        }
//        if (bestAccuracy >= 0.8) {
//            // 保存最优参数到数据库和缓存
//            slopeStableSettingService.updateById(bestSlopeSetting);
//            rockSlopeStableSettingService.updateById(bestRockSetting);
//            soilRockSlopeSettingService.updateById(bestSoilRockSetting);
//            redisUtil.set(CACHE_KEY_SLOPE, bestSlopeSetting);
//            redisUtil.set(CACHE_KEY_ROCK_SLOPE, bestRockSetting);
//            redisUtil.set(CACHE_KEY_SOIL_ROCK_SLOPE, bestSoilRockSetting);
//            return Result.OK("参数优化完成，准确率：" + bestAccuracy);
//        } else {
//            return Result.error("未能达到80%准确率，最高仅为：" + bestAccuracy);
//        }
//    }
//
//	 return Result.OK("添加成功！");

